// 尾调用优化
/**
 * 尾调用优化
 * 作用：可以减少不必要的栈帧常驻内存
 * 满足条件：
 * 1 必须在严格模式下调用（避免使用func.caller//func.arguments）
 * 2 外部函数的返回值必须是对尾调用函数的调用
 * es6优化前下面函数的调用过程：
 * 1 执行到outerFunc函数，第一个栈帧被推入栈上
 * 2 执行outerFunc函数，遇到return语句，要执行innerFunc函数
 * 3 执行innerFunc函数，第二个栈帧被推入栈上
 * 4 执行innerFunc的代码，并得到返回值，并弹出栈
 * 5 outerFunc得到innerFunc的返回值，返回
 * 6 outerFunc对应的栈帧弹出栈。
 * es6优化后：
 * 1 执行到outerFunc函数，第一个栈帧被推入栈上
 * 2 执行outerFunc函数，遇到return语句，要执行innerFunc函数
 * 3 这是发现可以直接把outerInner的栈帧弹出，因为innerFunc返回值刚好是outerFunc的返回值，且没有依赖
 * 4 弹出outerFunc的栈帧
 * 5 执行innerFunc函数，栈帧推到栈上
 * 6 执行innerFunc函数，计算返回值
 * 7 innerFunc的栈帧弹出栈。
 */
function innerFunc() {}
function outerFunc() {
  return innerFunc();
}

// 一下几种不符合尾调用
function outerFunc1() {
  return innerFunc() + innerFunc();
}

function outerFunc2() {
  const result = innerFunc();
  return result;
}

// 无优化：有闭包
function outerFunc3(a) {
  const innerFunc = function () {
    console.log(a);
  };
  return innerFunc();
}

// 有优化：栈帧销毁前执行参数计算
function outerFunction(a, b) {
  return innerFunc(a + b);
}

// 有优化：初始返回值不涉及栈帧
function outerFunction1(a, b) {
  if (a < b) {
    return a;
  }
  return innerFunc(a + b);
}

// 有优化：两个内部函数都在尾部
function outerFunction2(condition) {
  return condition ? innerFunctionA() : innerFunctionB();
}
